﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for MazeDataGen
/// </summary>
public class MazeDataGen
{
    private int height;
    private int width;
    private int[,] numMap;
    private Random rand = new Random();

    public MazeDataGen(int height, int width)
    {
        this.height = height;
        this.width = width;
    }

    public Cell[] GenerateNewMaze()
    {
        numMap = new int[height,width];
        for (int m = 0; m < height; m++)
        {
            for (int n = 0; n < width; n++)
            {
                numMap[m, n] = -1;
            }
        }
        CreateNumMap(height/2, width/2, 0); //starts in the middle of maze;
        Cell[] cells = new Cell[height*width];
        numMap[0, 0] = numMap[0, 0] ^ 8; //made the entry point
        numMap[height - 1, width - 1] = numMap[height - 1, width - 1] ^ 2; //made the exit point
        for (int m = 0; m < height; m++)
        {
            for (int n = 0; n < width; n++)
            {
                Cell newCell = new Cell { posX = n, posY = m, wallType = numMap[m, n], debug = (m + 1) * (n + 1) - 1 };
                cells[m*width+n] = newCell;
            }
        }

        return cells;
    }

    private void CreateNumMap(int m, int n, int o)
    {
        List<int> directs = new List<int> {0, 1, 2, 3}; //Store unused direction
        int last = 0;
        switch (o)
        {
            case 1:
                last = 4;
                break;
            case 2:
                last = 8;
                break;
            case 4:
                last = 1;
                break;
            case 8:
                last = 2;
                break;
        }
        numMap[m, n] = last;
        //test-begin
        string s = "";
        for (int f = 0; f < height; f++)
        {
            for (int g = 0; g < width; g++) s += numMap[f, g].ToString() + ",";
            s += "\r\n";
        }
        //test-end
        while (directs.Count > 0)
        {
            int x = m;
            int y = n;
            int d = rand.Next(directs.Count);
            int t = 0;
            switch (directs[d])
            {
                case 0:
                    x--;
                    t = 8;
                    break;
                case 1:
                    y++;
                    t = 4;
                    break;
                case 2:
                    x++;
                    t = 2;
                    break;
                case 3:
                    y--;
                    t = 1;
                    break;
            }
            directs.RemoveAt(d); //delete used direction
            if (x < height && y < width && x >= 0 && y >= 0 && numMap[x, y] == -1)
                //if inside the border and havent been visited
            {
                last = t ^ last;
                numMap[m, n] = last;
                //test-begin
                string ss = "";
                for (int f = 0; f < height; f++)
                {
                    for (int g = 0; g < width; g++) ss += numMap[f, g].ToString() + ",";
                    ss += "\r\n";
                }
                //test-end
                CreateNumMap(x, y, t);
                Console.WriteLine(x.ToString() + y.ToString() + t.ToString());
            }
        }
    }
}

/// <summary>
/// Raw cell data contain position and wall type, will be
/// used to form a collection that represents the maze data, and
/// serialized to parse to invoker.
/// </summary>
public struct Cell
{
    public int posX;
    public int posY;
    public int wallType;
    public int debug;
}